/*
 * Copyright 2008 Mark Davidson.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package org.doofer.test

import com.documentum.fc.client.*
import com.documentum.fc.common.*
import org.doofer.*

class ObjectUtilTest extends DooferBaseTest {

    def params = null
    def su = null
    def ou = null

    /**
     * Constructor
     */
    ObjectUtilTest() {}

    void setUp() {
        super.setUp()
        params = [username: username, password: password, repository: repository]
        su = new SessionUtil(params)
        ou = new ObjectUtil()
    }

    void testGetObject() {
        println "testing getObject()"
        su.useSession { session ->
            def cabinetName = 'Templates'
            def path = "/$cabinetName"
            def qual = "dm_cabinet where object_name = '$cabinetName'"
            def object = null
            def objectId = null

            object = ou.getObject(session: session, path: path)
            assert(object)
            assertEquals(cabinetName, object.objectName)
            objectId = object.objectId.id

            object = ou.getObject(session: session, qualification: qual)
            assert(object)
            assertEquals(cabinetName, object.objectName)

            object = ou.getObject(session: session, objectId: objectId)
            assert(object)
            assertEquals(cabinetName, object.objectName)        }
    }

    void testCreateObject() {
        println "testing createObject()"
        su.useSession { session ->
            def parentFolder = "/$username"
            def objectType = "dm_document"
            def objectName = "Test Doc"
            def title = "Test Title"
            def object
            def params = [session: session, objectType: objectType, objectName: objectName, link: parentFolder]

            //println "creating object without closure"
            object = ou.createObject(params)
            assert(object)
            //println "created doc: $objectName [${object.objectId.id}]"
            assertEquals(objectName, object.getString('object_name'))
            object.destroy()
            //println "zapped doc: $objectName"

            //println "creating object with closure"
            object = ou.createObject(params) { obj ->
                obj.setString('title', title)
            }
            assert(object)
            //println "created doc: $objectName [${object.objectId.id}]"
            assertEquals(objectName, object.getString('object_name'))
            assertEquals(title, object.getString('title'))
            object.destroy()
            //println "zapped doc: $objectName"

            //println "creating object with casting"
            object = ou.createObject(params) { obj ->
                def doc = obj as IDfDocument
                doc.setTitle(title)
            }
            assert(object)
            //println "created doc: $objectName [${object.objectId.id}]"
            assertEquals(objectName, object.getString('object_name'))
            assertEquals(title, object.getString('title'))
            object.destroy()
            //println "zapped doc: $objectName"
        }
    }

    void testSplitPath() {
        println "testing splitPath()"
        def path = '/path/to/my/document.txt'
        def p1 = ['path', 'to', 'my', 'document.txt']
        def p2 = ['/path', '/path/to', '/path/to/my', '/path/to/my/document.txt']

        assertEquals(p1, ou.splitPath(path: path))
        assertEquals(p2, ou.splitPath(path: path, absolute: true))
    }

    void testCreateFolder() {
        println "testing createFolder()"
        su.useSession { session ->
            def path = "/$username/level2/level3"
            def folder = null

            //println "creating folder [$path]"
            folder = ou.createFolder(session: session, path: path)
            assert(folder)
            //println "created folder [$folder.objectId.id]"

            folder = session.getFolderByPath(path)
            assert(folder)

            //println "zapping folders..."
            folder.destroy()
            session.getFolderByPath("/$username/level2").destroy()
            //println "done zapping folders"
        }
    }

    void testDeltree() {
        println "testing deltree()"
        su.useSession() { session ->
            def doc = ou.createObject(session: session, objectType: 'dm_document', objectName: 'test', link: "/$username/doofer/subfolder")
            if(doc) {
                ou.deltree(session: session, path: "/$username/doofer")
                assertNull(session.getObjectByPath("/$username/doofer/subfolder/test"))
                assertNull(session.getObjectByPath("/$username/doofer/subfolder"))
                session.getObjectByPath("/$username/doofer").destroy()
                assertNull(session.getObjectByPath("/$username/doofer"))
            }
        }
    }

    void testWalkObjects() {
        println "testing walkObjects()"
        
        def containers = ['AcsConfig', 'Applications', 'DataDictionary', 'Methods', 'Modules', 'TBO', 'SBO']
        def objects = ['assume_user', 'validate_user']
        def failed = false
        def matchedContainers = []
        def matchedObjects = []

        try {
            su.useSession { session ->
                ou.walkObjects(session: session, path: '/System', recursive: true) { object ->
                    if(containers.contains(object.objectName)) matchedContainers << object.objectName
                    else if(objects.contains(object.objectName)) matchedObjects << object.objectName
                }
            }
        } catch(Throwable t) {
            println "Detected error: $t.message"
            failed = true
        }

        assertFalse(failed)
        //println "matchedContainers = $matchedContainers"
        //println "matchedObjects = $matchedObjects"
        assertEquals(containers.size(), matchedContainers.size())
        assertEquals(objects.size(), matchedObjects.size())
    }

    void testImportDocument() {
        println "testing importDocument()"
        def failed = false

        try {
            su.useSession { session ->
                def sourcePath = 'samples/data/OSS/The Cathedral And The Bazaar.pdf'
                def targetPath = "/$username"
                def objectType = 'dm_document'
                def title = 'The Cathedral And The Bazaar'
                def params = [session: session, sourcePath: sourcePath, targetPath: targetPath, objectType: objectType]

                ou.importDocument(params) { it.title = title }
                def doc = session.getObjectByPath("$targetPath/$title")
                assert(doc)
                assertEquals(title, doc.objectName)
                assertEquals(title, doc.title)
                assertEquals(objectType, doc.typeName)
                assertEquals('pdf', doc.contentType)
                doc.destroy()
            }
        } catch(Throwable t) {
            println "Detected error: $t.message"
            failed = true
        }

        assertFalse(failed)
    }
}